import os
import json
import copy
import threading
import concurrent.futures
from datetime import datetime
from DrissionPage import ChromiumOptions
from omegaconf import OmegaConf

# 导入原始注册功能
import sys
import os.path as path
# 确保cursor_register.py可以被导入
sys.path.append(path.dirname(path.dirname(path.dirname(__file__))))
from cursor_register import register_cursor_core as original_register_cursor_core
from cursor_register import generate_password, load_outlook_accounts, OUTLOOK_ACCOUNTS_JSON, REGISTERED_ACCOUNTS_JSON

def load_registered_accounts():
    """加载已注册的账号"""
    registered_accounts = {}
    try:
        if os.path.exists(REGISTERED_ACCOUNTS_JSON):
            with open(REGISTERED_ACCOUNTS_JSON, 'r', encoding='utf-8') as file:
                data = json.load(file)
                if "accounts" in data and isinstance(data["accounts"], list):
                    # 转换为以email为键的字典，便于快速查找
                    for account in data["accounts"]:
                        if "username" in account and "cursor_password" in account and "token" in account:
                            registered_accounts[account["username"]] = account
    except Exception as e:
        print(f"加载已注册账号失败: {str(e)}")
    
    return registered_accounts

def save_registered_accounts(registered_accounts):
    """保存已注册账号到JSON文件"""
    try:
        # 将字典转换回列表
        accounts_list = list(registered_accounts.values())
        data = {"accounts": accounts_list}
        
        with open(REGISTERED_ACCOUNTS_JSON, 'w', encoding='utf-8') as file:
            json.dump(data, file, indent=4, ensure_ascii=False)
        return True
    except Exception as e:
        print(f"保存已注册账号失败: {str(e)}")
        return False

def check_registered_account(email, registered_accounts):
    """检查账号是否已注册"""
    return email in registered_accounts and registered_accounts[email].get("token") and registered_accounts[email].get("cursor_password")

# 重新定义register_cursor_core以支持日志回调和自动关闭浏览器
def register_cursor_core(config, options, outlook_account, log_callback=None, auto_close_browser=True, registered_accounts=None):
    """带日志回调的Cursor注册核心函数"""
    # 创建日志函数
    def log_message(message):
        # 如果提供了回调，使用回调输出日志；否则使用print
        if log_callback:
            log_callback(message)
        else:
            print(message)
    
    try:
        # 记录使用的账号
        email = outlook_account.get('email', '')
        
        # 检查账号是否已注册
        if registered_accounts and check_registered_account(email, registered_accounts):
            log_message(f"账号 {email} 已经注册过，跳过注册")
            # 返回已注册的账号信息
            return registered_accounts[email]
        
        log_message(f"使用Outlook账号: {email}")
        
        # 调用原始注册函数
        result = original_register_cursor_core(config, options, outlook_account)
        
        # 检查result是否包含browser对象
        browser = None
        if isinstance(result, dict) and 'browser' in result:
            browser = result.pop('browser')  # 从结果中移除浏览器对象并保存引用
            log_message("找到浏览器对象")
        
        # 如果需要自动关闭浏览器，并且有浏览器对象
        if auto_close_browser and browser:
            log_message(f"正在关闭浏览器")
            try:
                browser.quit(force=True, del_data=True)
                log_message(f"浏览器已关闭")
            except Exception as e:
                log_message(f"关闭浏览器出错: {str(e)}")
        
        # 检查注册结果是否成功（需要有token和cursor_password）
        if result and result.get("token") and result.get("cursor_password"):
            log_message(f"账号 {email} 注册成功，获取到token")
            return result
        else:
            log_message(f"账号 {email} 注册失败")
            return None
            
    except Exception as e:
        log_message(f"注册过程出错: {str(e)}")
        return None

def register_cursor(config, chrome_options=None, stop_check_callback=None, log_callback=None):
    """
    Register multiple Cursor accounts based on configuration
    """
    try:
        # 创建日志函数
        def log_message(message):
            # 如果提供了回调，使用回调输出日志；否则使用print
            if log_callback:
                log_callback(message)
            else:
                print(message)
        
        # 加载已注册账号
        registered_accounts = load_registered_accounts()
        log_message(f"已加载 {len(registered_accounts)} 个已注册账号")
        
        # Check if stop requested initially
        if stop_check_callback and stop_check_callback():
            log_message("注册已取消")
            return []
            
        # Load accounts
        accounts = load_outlook_accounts()
        if not accounts:
            log_message("未找到可用账号")
            raise ValueError("No accounts available")
        
        # 记录账号数量
        log_message(f"已从{OUTLOOK_ACCOUNTS_JSON}加载{len(accounts)}个Outlook账号")
            
        # Create a copy of accounts to avoid modifying the original list
        available_accounts = copy.deepcopy(accounts)
        
        # Get config values
        number = config.get("number", 1)
        max_workers = config.get("max_workers", 5)
        auto_close_browser = config.get("auto_close_browser", True)
        
        log_message(f"开始注册 {number} 个账号，使用 {max_workers} 个线程")
        log_message(f"自动关闭浏览器: {'启用' if auto_close_browser else '禁用'}")
        
        # Register accounts
        results = []
        
        # Create options
        options = ChromiumOptions()
        options.auto_port()
        options.new_env()
        
        # 使用turnstilePatch以绕过验证码检测
        turnstile_patch_path = os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "turnstilePatch"))
        if os.path.exists(turnstile_patch_path):
            log_message("加载TurnstilePatch扩展")
            options.add_extension(turnstile_patch_path)
        
        # 应用chrome设置
        if chrome_options:
            log_message("应用自定义Chrome设置")
            # 这里可以添加来自settings的chrome选项
        
        # 设置无头模式（如果启用）
        if config.get("enable_headless", False):  # 默认不启用无头模式
            log_message("启用无头模式")
            options.headless()
        else:
            log_message("关闭无头模式，将显示浏览器界面")
        
        # Create a wrapper for the stop check callback
        stop_requested = [False]  # Using a list to make it mutable in closures
        
        def check_stop():
            if stop_check_callback:
                stop_requested[0] = stop_check_callback()
            return stop_requested[0]
        
        # 修改register_cursor_core_wrapper来使用原始的register_cursor_core函数
        def register_cursor_core_wrapper(account, options_thread):
            if check_stop():
                return None
            
            try:
                # 调用带日志功能的注册核心函数
                result = register_cursor_core(
                    config, 
                    options_thread, 
                    account,
                    log_callback=log_callback,
                    auto_close_browser=auto_close_browser,
                    registered_accounts=registered_accounts
                )
                # 周期性检查是否要求停止
                if check_stop() or not result:
                    return None
                return result
            except Exception as e:
                log_message(f"注册错误: {str(e)}")
                return None
        
        # 使用多线程执行注册
        with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
            futures = []
            
            # 提交作业到执行器
            for i in range(min(number, len(available_accounts))):
                # 检查是否请求在提交更多作业前停止
                if check_stop():
                    log_message("注册已取消，停止提交更多任务")
                    break
                
                account = available_accounts[i]
                options_thread = copy.deepcopy(options)
                futures.append(executor.submit(
                    register_cursor_core_wrapper,
                    account,
                    options_thread
                ))
            
            # 处理结果
            for future in concurrent.futures.as_completed(futures):
                # 检查是否请求在处理更多结果前停止
                if check_stop():
                    # 取消任何待处理的future
                    log_message("注册已取消，停止处理结果")
                    for f in futures:
                        if not f.done():
                            f.cancel()
                    break
                
                try:
                    result = future.result()
                    if result:
                        # 添加到结果，并更新已注册账号
                        results.append(result)
                        if result.get("username") and result.get("token") and result.get("cursor_password"):
                            registered_accounts[result["username"]] = result
                except Exception as e:
                    if not check_stop():  # 只有在未停止时才打印错误
                        log_message(f"线程执行错误: {str(e)}")
        
        # 保存已注册账号
        if results:
            save_registered_accounts(registered_accounts)
            log_message(f"已保存 {len(results)} 个新注册账号")
        
        return results
        
    except Exception as e:
        if log_callback:
            log_callback(f"注册过程出错: {str(e)}")
        else:
            print(f"注册过程出错: {str(e)}")
        return [] 